﻿
@{
    ViewBag.Title = "Cube";
}

<h2>Cube - Fast & Easy OLAP</h2>
<p>This demo Cube has 3 dimensions,<b>421,632</b> Nodes. A background work keeps generating random numbers for all 5-minute slots in the current hour. And the numbers are automatically rolled up along dimensions with statistics such as minimum, maximum, and median automatically calculated. The background worker performs about <b>50</b> updates/rollups per second. And queries can be done in near real-time.</p>
<h3>Hourly view</h3>
<div style="display:inline">
    <table style="display:inline"><tr><td><canvas id="hourCanvas0" style="width:400px;height:200px"></canvas></td></tr><tr><td><b>Slot 0</b></td></tr></table>
</div>
<div style="display:inline">
    <table style="display:inline"><tr><td><canvas id="hourCanvas1" style="width:400px;height:200px"></canvas></td></tr><tr><td><b>Slot 1</b></td></tr></table>
</div>
<div style="display:inline">
    <table style="display:inline"><tr><td><canvas id="hourCanvas2" style="width:400px;height:200px"></canvas></td></tr><tr><td><b>Slot 2</b></td></tr></table>
</div>
<div style="display:inline">
    <table style="display:inline"><tr><td><canvas id="hourCanvas3" style="width:400px;height:200px"></canvas></td></tr><tr><td><b>Slot 3</b></td></tr></table>
</div>
@section Scripts {
    <script>
        function canvasData() {
            var self = this;
            self.currentValues = new Array();
            self.tensionValues = new Array();
            self.targetValues = new Array();
            self.first = true;
            self.min = 0;
            self.max = 100;
            self.currentMin = 0;
            self.currentMax = 100;
            self.tensionMin = 0;
            self.tensionMax = 0;
            self.targetMin = 0;
            self.targetMax = 100;
            self.update = function(newData)
            {
                if (self.first)
                {
                    self.first = false;
                    for (var i = 0; i < newData.length; i++)
                        self.currentValues[i] = 0;
                }
                for (var i = 0; i < newData.length-1; i++) {
                    self.targetValues[i] = newData[i].Value;
                    self.tensionValues[i] = newData[i].Value - self.currentValues[i];
                }
                self.targetMin = newData[newData.length - 1].Min;
                self.targetMax = newData[newData.length - 1].Max;
                self.tensionMin = self.targetMin - self.currentMin;
                self.tensionMax = self.targetMax - self.currentMax;
            }
            self.progress = function()
            {
                for (var i = 0; i < self.currentValues.length-1; i++) {
                    if ((self.targetValues[i] > self.currentValues[i] && self.tensionValues[i] > 0)
                        ||
                        (self.targetValues[i] < self.currentValues[i] && self.tensionValues[i] < 0))
                        self.currentValues[i] += self.tensionValues[i]/10;
                }
                if ((self.targetMin > self.currentMin && self.tensionMin > 0)
                    ||
                    (self.targetMin < self.currentMin && self.tensionMin < 0))
                    self.currentMin += self.tensionMin/10;
                if ((self.targetMax > self.currentMax && self.tensionMax > 0)
                   ||
                   (self.targetMax < self.currentMax && self.tensionMax < 0))
                    self.currentMax += self.tensionMax/10;
            }
        }
        var count0 = 9;
        var count1 = 9;
        var count2 = 9;
        var count3 = 9;
        var hourCanvasData0 = new canvasData();
        var hourCanvasData1 = new canvasData();
        var hourCanvasData2 = new canvasData();
        var hourCanvasData3 = new canvasData();

        $(function () {
            hourCanvas0.width = 400;
            hourCanvas0.height = 200;
            hourCanvas1.width = 400;
            hourCanvas1.height = 200;
            hourCanvas2.width = 400;
            hourCanvas2.height = 200;
            hourCanvas3.width = 400;
            hourCanvas3.height = 200;
            setInterval(refreshHourData0, 50);
            setInterval(refreshHourData1, 50);
            setInterval(refreshHourData2, 50);
            setInterval(refreshHourData3, 50);
        });
        function refreshHourData0() {
            count0++;
            if (count0 >= 9) {
                $.getJSON('/api/RandomCubeData/GetHour?id=0', function (json) {
                    hourCanvasData0.update(json);
                });
                count0 = 0;
            }
            hourCanvasData0.progress();
            refreshCanvas(hourCanvas0, hourCanvasData0.currentValues, hourCanvasData0.currentMin, hourCanvasData0.currentMax);
        }
        function refreshHourData1() {
            count1++;
            if (count1 >= 9) {
                $.getJSON('/api/RandomCubeData/GetHour?id=1', function (json) {
                    hourCanvasData1.update(json);
                });
                count1 = 0;
            }
            hourCanvasData1.progress();
            refreshCanvas(hourCanvas1, hourCanvasData1.currentValues, hourCanvasData1.currentMin, hourCanvasData1.currentMax);
        }
        function refreshHourData2() {
            count2++;
            if (count2 >= 9) {
                $.getJSON('/api/RandomCubeData/GetHour?id=2', function (json) {
                    hourCanvasData2.update(json);
                });
                count2 = 0;
            }
            hourCanvasData2.progress();
            refreshCanvas(hourCanvas2, hourCanvasData2.currentValues, hourCanvasData2.currentMin, hourCanvasData2.currentMax);
        }
        function refreshHourData3() {
            count3++;
            if (count3 >= 9) {
                $.getJSON('/api/RandomCubeData/GetHour?id=3', function (json) {
                    hourCanvasData3.update(json);
                });
                count3 = 0;
            }
            hourCanvasData3.progress();
            refreshCanvas(hourCanvas3, hourCanvasData3.currentValues, hourCanvasData3.currentMin, hourCanvasData3.currentMax);
        }
        function refreshCanvas(canvas, data, min, max)
        {
            var context = canvas.getContext('2d');
            var length = data.length;
            context.fillStyle = 'rgba(89,181,230,0.5)';
            context.strokeStyle = "rgba(89,181,230,1.0)";
            context.clearRect(0, 0, canvas.width, canvas.height);
            context.beginPath();
            var bar = canvas.width / length;
            context.moveTo(0.5 * bar, canvas.height);
            for(var i = 0; i < length-1; i++)
            {
                context.lineTo((i + 0.5) * bar, canvas.height - data[i] * canvas.height/100);
            }
            context.lineTo((length - 1.5) * bar, canvas.height);
            context.closePath();
            context.fill();
            context.stroke();
            context.strokeStyle = "rgba(255,0,0,0.4)";
            context.beginPath();
            context.moveTo(0, canvas.height - min * canvas.height / 100);
            context.lineTo(canvas.width - bar, canvas.height - min * canvas.height / 100);
            context.closePath();
            context.stroke();
            context.font = "8px Calibri";
            context.fillStyle = 'rgba(255,0,0,0.8)';
            context.fillText(min.toFixed(2), canvas.width - bar + 2, canvas.height - min * canvas.height / 100 + 3);
            context.strokeStyle = "rgba(0,128,0,0.4)";
            context.beginPath();
            context.moveTo(0, canvas.height - max * canvas.height / 100);
            context.lineTo(canvas.width - bar, canvas.height - max * canvas.height / 100);
            context.fillStyle = 'rgba(0,128,0,0.8)';
            context.fillText(max.toFixed(2), canvas.width - bar + 2, canvas.height - max * canvas.height / 100 + 3);
            context.closePath();
            context.stroke();
        }
    </script>
}